#
# Sorto, the sorting game
# Copyright (C) 2012 Ralph Preston
# ralph.preston@gmail.com
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to:
#
# Free Software Foundation, Inc.
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301
# USA.
#
import copy
import types

class SortoBoard(object):
    EMPTY = 0

    def __init__(self, board=None):
        if not board:
            board = [self.EMPTY] * 36
            pass
        if type(board) is types.DictType:
            for key in board:
                setattr(self, key, board[key])
                pass
            pass
        else:
            self._board = board
            pass
        return

    def __str__(self):
        for ii in range(6):
            row = self._board[ii*6:ii*6+6]
            if ii == 0:
                res = '      (1 - 4) : '
            elif ii == 1:
                res = '%s\n      (5 - 7) : ' % res
            elif ii == 2:
                res = '%s\n      (8 -10) : ' % res
            elif ii == 3:
                res = '%s\n      (11-13) : ' % res
            elif ii == 4:
                res = '%s\n      (14-16) : ' % res
            elif ii == 5:
                res = '%s\n      (17-20) : ' % res
                pass

            for item in row:
                if not item:
                    res = '%s    ,' % res
                else:
                    val = str(item)
                    pad = 4-len(val)
                    res = '%s%s%s,' % (res, ' '*pad, val)
                    pass
                pass
            pass

        res = res[:-1] # remove the last comma
        return res
    
    def __len__(self):
        return len(self._board)
 
    def __getitem__(self, key):
        return self._board[key]

    def __setitem__(self, key, value):
        self._board[key] = value
        return

    def index(self, value):
        return self._board.index(value)

    def legal_places_for_roll_and_counter(self, roll, counter):
        """
        Finds the legal places to play the counter. Assumes the
        counter is not on the board.

        returns a list of indexes that are legal plays.
        """
        legal = []
        
        (index_1, index_2) = self.convert_roll_to_index(roll)
        # Check the 1 or 2 spaces that are for the roll
        if self._board[index_1] == self.EMPTY:
            legal.append(index_1)
            pass
        if index_2 and self._board[index_2] == self.EMPTY:
            legal.append(index_2)
            pass
        # If either of the spaces are available the counter must be
        # played there.
        if legal: return legal
        
        # If both spaces are covered find the ends of the chain Search
        # for a free space lower than the roll
        for ii in range(index_1, -1, -1):
            if self._board[ii] == self.EMPTY:
                legal.append(ii)
                break
            pass
        # Search for a free space higher than the roll
        for ii in range(index_1, 36):
            if self._board[ii] == self.EMPTY:
                legal.append(ii)
                break
            pass
        return legal
    
    def convert_roll_to_index(self, roll):
        """
        Convert a die roll to index(s) that can be used to access into
        the board list.
        """
        index_2 = None
        if roll < 3:
            index_1 = roll - 1
        elif roll < 19:
            _tmp = (roll-2) * 2
            index_1 = _tmp
            index_2 = _tmp + 1
        else:
            index_1 = 34 + (roll - 19)
            pass
        return (index_1, index_2)
    
    def convert_index_to_board_space(self, index):
        """
        Convert an index into the board list into the number shown on
        a space
        """
        if index < 2:
            space = index + 1
        elif index < 35:
            _tmp = index / 2 # round down
            space = _tmp + 2
        else:
            space = 20
            pass
        return space

    def place_counter_on_index(self, counter, index):
        self._board[index] = counter
        return

    def longest_chain(self):
        # Determine the longest consecutive
        longest = 0
        count = 1
        last_number = None
        for ii in range(len(self._board)):
            if not last_number:
                if self._board[ii] != self.EMPTY:
                    last_number = self._board[ii]
                    pass
                continue

            if self._board[ii] != self.EMPTY:
                if last_number < self._board[ii]:
                    count += 1
                    last_number = self._board[ii]
                else:
                    count = 1                
                    pass
                pass
            if count > longest:
                longest = count
                pass
            pass
        return longest

    def remove_counter(self, counter):
        index = self._board.index(counter)
        self._board[index] = self.EMPTY
        return

    def get_counters(self):
        counters = copy.deepcopy(self._board)
        while self.EMPTY in counters:
            counters.remove(self.EMPTY)
            pass
        return counters

    pass # End of class SortoBoard
